﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using YawetagDemo.Framework.Impl.Services;
using YawetagDemo.Framework.Server.Data;
using YawetagDemo.Framework.Services;
using YawetagLib.System.Data;
using YawetagLib.System.ServiceModel;
using YawetagLib.System.Utilities;

namespace YawetagDemo.Framework.Server.Services
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Reentrant)]
    public class WCFServiceDispatcher : ServiceDispatcher, IWCFCoreService, IWCFMusicService
    {
        public WCFServiceDispatcher() 
        {
            RegisterService<CoreService>();
            RegisterService<MusicService>();

            Console.WriteLine("[...] Service created");
        }

        protected override void Dispose(bool disposing) 
        {
            base.Dispose(disposing);

            Console.WriteLine("[...] Service disposed");
        }

        WCFPerson IWCFCoreService.GetPerson(int personID)
        {
            return WCFPerson.Get(At<ICoreService>().GetPerson(personID), new Dictionary<object, object>());
        }

        IList<WCFPerson> IWCFCoreService.GetPersons()
        {
            IDictionary<object, object> references = new Dictionary<object, object>();

            return At<ICoreService>().GetPersons().Select(i => WCFPerson.Get(i, references)).ToList();
        }

        WCFPerson IWCFCoreService.CreatePerson(string name, DateTime? dob)
        {
            return WCFPerson.Get(At<ICoreService>().CreatePerson(name, dob), new Dictionary<object, object>());
        }

        WCFPerson IWCFCoreService.UpdatePerson(int personID, string name, DateTime? dob)
        {
            return WCFPerson.Get(At<ICoreService>().UpdatePerson(personID, name, dob), new Dictionary<object, object>());
        }

        void IWCFCoreService.DeletePerson(int personID)
        {
            At<ICoreService>().DeletePerson(personID);
        }

        WCFArtist IWCFMusicService.GetArtist(int artistID)
        {
            return WCFArtist.Get(At<IMusicService>().GetArtist(artistID), new Dictionary<object, object>());
        }

        IList<WCFArtist> IWCFMusicService.GetArtists()
        {
            IDictionary<object, object> references = new Dictionary<object, object>();

            return At<IMusicService>().GetArtists().Select(i => WCFArtist.Get(i, references)).ToList();
        }

        WCFArtist IWCFMusicService.CreateArtist(string name, DateTime? dob)
        {
            return WCFArtist.Get(At<IMusicService>().CreateArtist(name, dob), new Dictionary<object, object>());
        }

        WCFArtist IWCFMusicService.UpdateArtist(int artistID, string name, DateTime? dob)
        {
            return WCFArtist.Get(At<IMusicService>().UpdateArtist(artistID, name, dob), new Dictionary<object, object>());
        }

        void IWCFMusicService.DeleteArtist(int artistID)
        {
            At<IMusicService>().DeleteArtist(artistID);
        }

        WCFBand IWCFMusicService.GetBand(int bandID)
        {
            return WCFBand.Get(At<IMusicService>().GetBand(bandID), new Dictionary<object, object>());
        }

        IList<WCFBand> IWCFMusicService.GetBands()
        {
            IDictionary<object, object> references = new Dictionary<object, object>();

            return At<IMusicService>().GetBands().Select(i => WCFBand.Get(i, references)).ToList();
        }

        WCFBand IWCFMusicService.CreateBand(string name)
        {
            return WCFBand.Get(At<IMusicService>().CreateBand(name), new Dictionary<object, object>());
        }

        WCFBand IWCFMusicService.UpdateBand(int bandID, string name)
        {
            return WCFBand.Get(At<IMusicService>().UpdateBand(bandID, name), new Dictionary<object, object>());
        }

        void IWCFMusicService.DeleteBand(int bandID)
        {
            At<IMusicService>().DeleteBand(bandID);
        }

        void IWCFMusicService.AddArtistToBand(int bandID, int artistID)
        {
            At<IMusicService>().AddArtistToBand(bandID, artistID);
        }

        void IWCFMusicService.RemoveArtistFromBand(int bandID, int artistID)
        {
            At<IMusicService>().RemoveArtistFromBand(bandID, artistID);
        }

        WCFAlbum IWCFMusicService.GetAlbum(int albumID)
        {
            return WCFAlbum.Get(At<IMusicService>().GetAlbum(albumID), new Dictionary<object, object>());
        }

        WCFAlbum IWCFMusicService.CreateAlbum(int bandID, string name, DateTime releaseDate)
        {
            return WCFAlbum.Get(At<IMusicService>()
                .CreateAlbum(bandID, name, releaseDate), new Dictionary<object, object>());
        }

        WCFAlbum IWCFMusicService.UpdateAlbum(int albumID, string name, DateTime releaseDate)
        {
            return WCFAlbum.Get(At<IMusicService>()
                .UpdateAlbum(albumID, name, releaseDate), new Dictionary<object, object>());
        }

        void IWCFMusicService.RankAlbum(int albumID, int personID, byte stars)
        {
            At<IMusicService>().RankAlbum(albumID, personID, stars);
        }

        void IWCFMusicService.DeleteAlbum(int albumID)
        {
            At<IMusicService>().DeleteAlbum(albumID);
        }

        public void LogArtists()
        {
            At<IMusicService>().LogArtists(
                a => GetCallbacks<IWCFMusicServiceCallbacks>().GetArtistForLogging(WCFArtist.Get(a, new Dictionary<object, object>())));
        }

        PagedResultInfo<WCFAlbumRankingItem> IWCFMusicService.GetAlbumRankingItems(string filterCriteria, string sortExpression, 
            int startRowIndex, int? maximumRows)
        {
            return At<IMusicService>()
                .GetAlbumRankingItems(filterCriteria, sortExpression, startRowIndex, maximumRows)
                .Select(WCFAlbumRankingItem.Get);
        }
    }
}
